/**
 * Created by Anard on 2017/4/19.
 */
var userDao = require('../mysql/userDao.js');
var md5 = require('md5');
var net = require('net');
var http = require('http');
var schedule = require('node-schedule');
var variable = require('../../config/variable.js');
var toGate = require('../util/toGate.js');

var playerList = {};
var timeoutA = variable.config.timeoutA * 1000;
var timeoutB = variable.config.timeoutB * 1000;
var argv = process.argv.splice(2);
var socketPort = argv[0];

net.createServer(function (c) { // Connection监听器
    toGate.setLink(c);
    c.on("end", function () {
        console.log('连接断开')
    });
    c.on("error", function () {
        //console.error('连接错误')
    });
    c.on('data', function (message) {
        var obj = JSON.parse(message.toString());
        switch (obj.action) {
            case 'matchStart':
                if (!obj.userId) {
                    toGate.send(obj.uuid, 'error', {'code': 10021});
                    return false;
                }
                var userModel = new userDao();
                userModel.inId(obj.userId, function (err, res) {
                    if (res == null) {
                        toGate.send(obj.uuid, 'error', {'code': 10022});
                        return false;
                    }
                    var data = res.res;
                    playerList[data.id] = {
                        'id': data.id,
                        'uuid': obj.uuid,
                        'lv': 1,
                        'lock': false
                    };
                    playerList[data.id].linkTime = new Date().getTime();
                    toGate.send(obj.uuid, 'matchStart');
                });
                break;
            case 'matchStop':
                if (!obj.userId) {
                    toGate.send(obj.uuid, 'error', {'code': 10021});
                    return false;
                }
                delete playerList[obj.userId];
                toGate.send(obj.uuid, 'matchStop');
                break;
        }
    });
}).listen(socketPort, function () {
    // Listening监听器
    console.log("排队服务器启动:" + socketPort);
});

var interval = function () {
    // 建立一个时间循环的默认规则
    var rule = new schedule.RecurrenceRule();
    // 增加一个每秒执行的内容
    var times = [];
    for (var i = 1; i < 60; i++) {
        times.push(i);
    }
    rule.second = times;
    // 开始动作
    schedule.scheduleJob(rule, function () {
        // 排队循环
        lineUp();
        // 检查排队时长
        timeOut();
        // 输出一堆乱七八糟的log
        //printLog();
    });
};

interval();

// 排队事件
var lineUp = function () {
    if (playerCount() <= 1) {
        return false;
    }
    // 用户分组，把不同等级的用户放到不同的组里
    var groups = {};
    var lvsGroup = false;
    var lvsNum = 0;
    for (var i in playerLists()) {
        if (!playerLists(i) || playerLists(i).lock == true) {
            continue;
        }
        // 以等级作为分组基准
        //var lv = Math.floor(playerLists(i).lv / variable.groupLevel);
        var lv = Math.floor(playerLists(i).lv);
        if (!groups[lv]) {
            groups[lv] = [];
            lvsNum++;
        }
        groups[lv].push(i);
    }
    if (lvsNum < 1) {
        return false;
    }
    // 把不同组里的用户配给房间
    for (var i in groups) {
        // 如果组里不够3人则跳过
        if (groups[i].length < 3) {
            continue;
        }
        //从组里取出3个人
        var selected = getRandomArrayElements(groups[i], 3);
        //var selected = groups[i].getRandomArrayElements(3);
        // 整理取出的3个人的资料发给房间服务器
        var userList = [];
        for (var j in selected) {
            if (!playerLists(selected[j])) {
                continue;
            }
            playerLists(selected[j]).lock = true;
            userList.push({
                'id': playerLists(selected[j]).id
            });
        }
        var userIds = [];
        for (var j in userList) {
            userIds.push(playerLists(userList[j].id).uuid);
        }
        createRoom(userIds, function (result) {
            if (result.code == 404) {
                for (var j in userList) {
                    playerLists(userList[j].id).lock = false;
                }
                console.log('房间服务器连接失败');
                return false;
            }
            if (result.code == 102) {
                for (var j in userList) {
                    if (result.inGameId.indexOf(playerLists(userList[j].id).uuid) >= 0) {
                        toGate.send(playerLists(userList[j].id).uuid, 'matchInGame');
                        delete playerList[userList[j].id];
                    } else {
                        playerLists(userList[j].id).lock = false;
                    }
                }
                return false;
            }
            if (result.code == 200) {
                var key = result.key;
                for (var j in userList) {
                    var local = result.player[playerLists(userList[j].id).uuid];
                    toGate.send(playerLists(userList[j].id).uuid, 'matchGame', {
                        'gameId': key.toString(),
                        'local': local
                    });
                    delete playerList[userList[j].id];
                }
                console.log('room:' + key + ',uuid:' + JSON.stringify(userIds));
            }
        });
    }
};

// 检查排队超时
var timeOut = function () {
    if (playerCount() <= 0) {
        return false;
    }
    var time = new Date().getTime();
    for (var i in playerLists()) {
        if (!playerLists(i)) {
            continue;
        }
        if (!playerLists(i)) {
            continue;
        }
        if (!playerLists(i).lock) {
            var c = time - playerLists(i).linkTime;
            if (c > timeoutB) {
                toGate.send(playerLists(i).uuid, 'matchEnd');
                delete playerList[i];
                continue;
            }
            if (c > timeoutA) {
                toGate.send(playerLists(i).uuid, 'matchOut');
            }
        }
    }
};

// 打印每秒的log
var printLog = function () {
    console.log('playCount:' + playerCount());
    for (var i in playerLists()) {
        console.log('user:' + JSON.stringify(playerLists(i)));
    }
};

var playerCount = function () {
    return Object.keys(playerList).length;
};

// 获取一个用户的信息
var playerLists = function (id) {
    if (!playerList) {
        playerList = {};
    }
    if (!id) {
        return playerList;
    }
    if (!playerList[id]) {
        playerList[id] = {};
    }
    return playerList[id];
};

function getRandomArrayElements(arr, count) {
    var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index;
    while (i-- > min) {
        index = Math.floor((i + 1) * Math.random());
        temp = shuffled[index];
        shuffled[index] = shuffled[i];
        shuffled[i] = temp;
    }
    return shuffled.slice(min);
}

function createRoom(userIds, callback) {
    var content = JSON.stringify(userIds);
    var options = {
        hostname: 'localhost',
        port: variable.game[0].http,
        path: '/create?uuid=' + content,
        method: 'GET',
        headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
    };
    http.get(options, function (res) {
        var receiveData = "";
        res.on('data', function (chunk) {
            receiveData += chunk;
        }).on('end', function () {
            callback(JSON.parse(receiveData));
        });
    }).on('error', function (e) {
        callback({'code': 404});
    });
}